﻿using System;
using System.Collections.Generic;
using System.Drawing;
using RRRSRoguelike.Entities.Props;
using RRRSRoguelike.Enums;
using RRRSRoguelike.Helpers;
using RRRSRoguelike.Managers;
using RRRSRoguelikeData;

namespace RRRSRoguelike.Entities.Creatures
{
	/// <summary>
	/// base class for all living entities
	/// </summary>
	public abstract class Creature : Tile
	{

		#region variables
		/// <summary>
		/// holds all the creature data from the data library 
		/// </summary>
		private CreatureData creatureData = new CreatureData();
		
		//Not sure this is the right way to do it.  A creature deadhandle may have an object and cause of death.
		public delegate void RaiseStatHandler(object sender, RaiseStatArgs e);
		/// <summary>
		/// Event called when creature dies.
		/// </summary>
		public event RaiseStatHandler CreatureDeadEvent;

		public Dictionary<Direction, int> Moves = new Dictionary<Direction, int>();

		//A list of custom flags that can be used for anything. Should be moved to creature data.
		public Dictionary<string,bool> Flags = new Dictionary<string, bool>();

		private ActionManager AM = DungeonManager.Instance.ActionManager;

		#endregion

		#region constructor


		public Creature(string imageCharacter, ConsoleColor color, Point position)
			: base(imageCharacter, color, position)
		{
			Setup();
		}

		public Creature(Point position, TileData tileData)
			: base(position, tileData)
		{
			Setup();
		}		
		
		public Creature()
		{ 
			Setup();
		}
		#endregion

		#region properties

		public bool Alive
		{
			get { return (Hits >= 0); }
		}
		#endregion

		#region methods
		/// <summary>
		/// Method for creature dead event.
		/// </summary>
		/// <param name="sender"></param>
		

		public int Hits
		{
			get
			{
				return creatureData.Hits;
			}
			set
			{
				creatureData.Hits = value;
				if (creatureData.Hits <= 0)
				{
					if (CreatureDeadEvent != null)
					{
						CreatureDeadEvent(this, new RaiseStatArgs("MonstersKilled",1));
					}
				}
			}
		}

		public void Setup()
		{
			Hits = 1;
		}
		
		//Populates the Moves list with distance from target to figure out the best move.
		public void CalculateMoves(Point target)
		{
			Moves.Clear();
			Moves.Add(Direction.N, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["N"]), target));
			Moves.Add(Direction.NE, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["NE"]), target));
			Moves.Add(Direction.E, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["E"]), target));
			Moves.Add(Direction.SE, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["SE"]), target));
			Moves.Add(Direction.S, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["S"]), target));
			Moves.Add(Direction.SW, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["SW"]), target));
			Moves.Add(Direction.W, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["W"]), target));
			Moves.Add(Direction.NW, Dungeon.GetDistance(Dungeon.AddPoints(Position, AM.DirectionVectors["NW"]), target));
		}



		#endregion

	}
}
